package com.itanqing.demo.study03;


import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.StandardCharsets;

/**
 * 通过Channel写数据到文件
 */
public class FileChannel01 {

    public static void main(String[] args) throws IOException {


//        write();
//        read();

        copy();
    }

    /**
     * 使用前面学习的ByteBuffer(缓冲), 和FileChannel(通道), 将 "Hello, Flower" 写入到 01.txt 中
     *
     * @throws IOException
     */
    public static void write() throws IOException {
        // 创建字符串
        String msg = "hello,Flower";

        // 创建输出流
        FileOutputStream fileOutputStream = new FileOutputStream("./study/study03/01.txt");

        // 获取FileChannel
        FileChannel channel = fileOutputStream.getChannel();

        // 创建字节缓冲区
        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);

        // 将字符串写入缓冲区
        byteBuffer.put(msg.getBytes(StandardCharsets.UTF_8));

        // 重置游标, 读写切换
        byteBuffer.flip();

        // 从缓冲区写入通道
        channel.write(byteBuffer);

        // 关闭文件流
        fileOutputStream.close();
    }

    /**
     * 使用前面学习后的ByteBuffer(缓冲)和Channel(通道), 将01.txt 中的数据读入到程序,并显示在控制台屏幕
     *
     * @throws IOException
     */
    public static void read() throws IOException {
        File file = new File("./study/study03/01.txt");

        // 创建输入流
        FileInputStream fileInputStream = new FileInputStream(file);

        // 获取FileChannel
        FileChannel channel = fileInputStream.getChannel();

        // 创建字节缓冲区
        ByteBuffer byteBuffer = ByteBuffer.allocate((int) file.length());

        // 将通道中的数据读入到Buffer
        channel.read(byteBuffer);

        // 因为没有使用Buffer 所以不需要flip

        // 通过构造String 传入buffer的 底层数组 转成字符串打印
        System.out.println(new String(byteBuffer.array()));

        // 关闭文件流
        fileInputStream.close();
    }

    public static void copy() throws IOException {
        FileInputStream fileInputStream = new FileInputStream("./study/study03/01.txt");
        FileOutputStream fileOutputStream = new FileOutputStream("./study/study03/01.txt.bak");

        FileChannel readChannel = fileInputStream.getChannel();
        FileChannel writeChannel = fileOutputStream.getChannel();

        ByteBuffer container = ByteBuffer.allocate(4);

        // 循环读取
        for (; ; ) {

            // 读取之前清空一下上一次的数据缓存
            container.clear();

            // 从通道中读取数据到Channel 返回值为读取数量
            int byteSize = readChannel.read(container);

            System.out.println(byteSize);

            // -1为读取完成 没有读取到任何数据
            if (byteSize == -1)
                break;

            if (byteSize == 3)
                System.out.println("到3了");

            // 读写切换 重置游标
            container.flip();

            // 为了避免写入空格 采用设置limit 限制
//            if(byteSize != container.capacity())
//                container.limit(byteSize);

            // 将Buffer中的数据写入到 Channel 返回值为写入的数量
            int write = writeChannel.write(container);
        }

        writeChannel.close();
        readChannel.close();
        fileOutputStream.close();
        fileInputStream.close();
    }

    public void copy2() throws IOException {
        FileInputStream fileInputStream = new FileInputStream("src/main/resources/01.jpeg");
        FileOutputStream fileOutputStream = new FileOutputStream("src/main/resources/02.jpeg");

        FileChannel sourceChannel = fileInputStream.getChannel();
        FileChannel targetChannel = fileOutputStream.getChannel();

        // 将源Channel的数据直接传输到目标Channel 从0开始 到 源的大小
        long length = targetChannel.transferFrom(sourceChannel, 0, sourceChannel.size());

        System.out.println(length);

        targetChannel.close();
        sourceChannel.close();
        fileOutputStream.close();
        fileInputStream.close();

    }

}
